package com.handy.database.page;

import java.util.ArrayList;
import java.util.Calendar;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.handy.database.DBUtil;

//import com.handy.dboperation.Database;

/**
 * 使用Apache dbutil访问数据库. <br>
 * 默认值:<br>
 * 每页最大显示记录数为20,setMaxLine(20).<br>
 * 页面翻页数量显示最大为10,setPageListCount(10).<br>
 * 
 * 使用方法:<br>
 * 1.实例化;<br>
 * 2.设置当前显示页 setSpecify(pageNo);<br>
 * 3.设置表名 setTableName("table name");<br>
 * 4.设置查询条件 setFindCondition("where ?=?");<br>
 * 5.设置每页最大显示条数 setMaxLine(20),每页最多显示20条.<br>
 * 6.设置页列表最大值setPageListCount(10),例如当前为第3页，则显示的页列表为1 2 3 4 5 6 7 8 9 10.<br>
 * 7.设置数据库类型.<br>
 * 8.设置数据源.<br>
 * 9.设置conditionParam,当findCondition中使用?来代替字段值时有效. 10.执行query().<br>
 * 11.取记录集recorders.
 * 
 * @author rocken.zeng@gmail.com
 * 
 */
public class HibernatePage extends AbstractPage {

	@SuppressWarnings("unchecked")
	@Override
	protected void recorders() {
		if (getDbKind() == 0) {
			log.error("请设定数据库类型,如设置数据库为ORACLE数据库:setDbKind(DB_ORACLE)");
			return;
		} else if (getTCount() == 0) {
			return;
		}

		String sql = "";
		switch (getDbKind()) {
		case DBUtil.DB_KIND_ORACLE:
			if (getColumns().equals("")) {
				sql = "from " + getClassName() + " " + getFindCondition();
			} else {
				sql = "SELECT " + getColumns() + " FROM " + getClassName()
				+ " " + getFindCondition();
			}
			break;
		case DBUtil.DB_KIND_MYSQL:
			if (getColumns().equals("")) {
				sql = "FROM " + getClassName() + " "
				+ getFindCondition();
			} else {
				sql = "SELECT " + getColumns() + " FROM " + getClassName()
						+ " " + getFindCondition();
			}
			break;
		case DBUtil.DB_KIND_SQLSERVER:
			break;
		case DBUtil.DB_KIND_DB2:
			break;
		case DBUtil.DB_KIND_INFORMIX:
			break;
		case DBUtil.DB_KIND_SYBASE:
			break;
		}

		if (log.isDebugEnabled()) {
			log.info(sql);
		}
		
		querySQL = sql;

//		BeanListHandler h = new BeanListHandler(bean);
		long start = 0;
		if (log.isDebugEnabled()) {
			start = Calendar.getInstance().getTimeInMillis();
			log.debug("start find  :" + start);
		}
		Session session = null;
		try {
			// QueryRunner run = new QueryRunner(Database
			// .DataSource(getDataSource()));
			
			Query query = null;
			SessionFactory sf = new Configuration().configure()
					.buildSessionFactory();
			session = sf.openSession();
			query = session.createQuery(sql);
			query.setFirstResult(getOffset()-1);
			query.setMaxResults(getMaxLine());
			if (null == getConditionParam()) {
				setRecorders((ArrayList)query.list());
			} else {
				setRecorders((ArrayList) query.list());
			}
			session.close();
		} catch (Exception e) {
			log.error(e.getMessage());
			
		}finally {
			log.debug("page finally");
			if (null != session) {
				session.close();
			}
		}

		if (log.isDebugEnabled()) {
			long end = Calendar.getInstance().getTimeInMillis();
			log.debug("finish find :" + end);
			log.debug("耗时：" + (end - start));
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void totalRecorder() {
		String sql = "SELECT count(*) FROM " + getClassName() + " "
				+ getFindCondition();
		if (getDbKind() == DBUtil.DB_KIND_SQLSERVER) {
			setFindCondition(getFindCondition().toUpperCase());
			int max = getFindCondition().indexOf("ORDER");
			sql = "SELECT count(*) FROM " + getClassName() + " "
					+ getFindCondition().substring(0, max);
		}
		if (log.isDebugEnabled()) {
			log.info(sql);
		}
		Session session = null;
		try {
			Query query = null;
			SessionFactory sf = new Configuration().configure()
					.buildSessionFactory();
			session = sf.openSession();
			query = session.createQuery(sql);
			if (null == getConditionParam()) {
				ArrayList _cols = (ArrayList) query.list();
				if (_cols != null) {
					if (getDbKind() == DBUtil.DB_KIND_ORACLE) {
						setTCount(((Integer) _cols.iterator().next())
								.intValue());
					} else if (getDbKind() == DBUtil.DB_KIND_MYSQL) {
						setTCount(((Integer) _cols.iterator().next()).intValue());
					} else if (getDbKind() == DBUtil.DB_KIND_SQLSERVER) {
						setTCount(((Integer) _cols.iterator().next())
								.intValue());
					}
				}
			} else {
				ArrayList _cols = (ArrayList)query.list();
				if (_cols != null) {
					if (getDbKind() == DBUtil.DB_KIND_ORACLE) {
						setTCount(((Integer) _cols.iterator().next())
								.intValue());
					} else if (getDbKind() == DBUtil.DB_KIND_MYSQL) {
						setTCount(((Long) _cols.iterator().next()).intValue());
					} else if (getDbKind() == DBUtil.DB_KIND_SQLSERVER) {
						setTCount(((Integer) _cols.iterator().next())
								.intValue());
					}
				}
			}
			session.close();
		} catch (Exception e) {
			log.error(e.getMessage());
		}finally {
			log.debug("page finally");
			if (null != session) {
				session.close();
			}
		}

	}

	private static final Log log = LogFactory.getLog(DBUtilPage.class);

	private String dataSource = null;// 数据库

	private String[] conditionParam;// 当findCondition中使用?来代替字段值时有效.

	private String conditionColumn = "id";// 用于分页的字段,默认使用id分页.

	private String className = "";// 所要检索的类名.

	public String getDataSource() {
		return dataSource;
	}

	public void setDataSource(String dataSource) {
		this.dataSource = dataSource;
	}

	public String[] getConditionParam() {
		return conditionParam;
	}

	public void setConditionParam(String[] conditionParam) {
		this.conditionParam = conditionParam;
	}

	public String getConditionColumn() {
		return conditionColumn;
	}

	public void setConditionColumn(String conditionColumn) {
		this.conditionColumn = conditionColumn;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}
}